package com.linkhub.oms.admin.modules.order.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.linkhub.oms.admin.modules.order.domain.param.ordersplit.OrderPackageParam;
import com.linkhub.oms.admin.modules.order.domain.vo.OrderAddressVO;
import com.linkhub.oms.admin.modules.order.domain.vo.OrderFulfillmentVO;
import com.linkhub.oms.admin.modules.order.domain.vo.OrderTabCountVO;
import com.linkhub.oms.admin.modules.order.domain.vo.orderdetail.OrderDetailVO;
import com.linkhub.oms.admin.modules.order.domain.vo.orderdetail.OrderLocalProductVO;
import com.linkhub.oms.admin.modules.order.domain.vo.orderdetail.OrderProductMatchVO;
import com.linkhub.oms.admin.modules.order.domain.vo.orderlist.OrderlistLineItemVO;
import com.linkhub.oms.admin.modules.order.domain.vo.orderlist.OrderlistVO;
import com.linkhub.oms.common.enums.mp.BoolEnum;
import com.linkhub.oms.common.enums.mp.CustomerBusinessStatusEnum;
import com.linkhub.oms.common.enums.mp.CustomerOrderStatusEnum;
import com.linkhub.oms.common.enums.mp.DataStatusEnum;
import com.linkhub.oms.common.enums.mp.OrderProductTypeEnum;
import com.linkhub.oms.common.util.QtBeanUtil;
import com.linkhub.oms.common.util.QtBigDecimalUtil;
import com.linkhub.oms.common.util.QtOptionalUtil;
import com.linkhub.oms.common.util.QtStreamUtil;
import com.linkhub.oms.entity.OrderAddressEntity;
import com.linkhub.oms.entity.OrderEntity;
import com.linkhub.oms.entity.OrderProductEntity;
import com.linkhub.oms.entity.innerproperties.OrderFulfillmentEntity;
import com.linkhub.oms.entity.resulttype.order.OrderInfoDO;
import com.linkhub.oms.entity.resulttype.order.OrderLocalProductDO;
import com.linkhub.oms.entity.resulttype.order.OrderShopProductDO;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @Description: OrderMappingAssist
 * @Author: echo
 * @Date: 2024/4/2 18:23
 * @Version: 1.0
 */
public class OrderMappingAssist {

    public static OrderlistVO mappingOrderlist(OrderInfoDO orderInfo) {
        OrderEntity order = orderInfo.getOrder();
        OrderlistVO vo = mappingCommonOrderlist(orderInfo);
        vo.setOrderStatus(order.getOrderStatus().getCode());
        vo.setOrderStatusDesc(order.getOrderStatus().getDesc());
        vo.setSplitFlag(order.getSplitFlag().getCode());
        vo.setCustomerOrderStatus(order.getCustomerOrderStatus().getCode());
        vo.setWayBillNumber(order.getWayBillNumber());
        List<OrderInfoDO> subOrders = orderInfo.getSubOrders();
        if (CollUtil.isNotEmpty(subOrders)) {
            vo.setSubOrders(QtStreamUtil.map(subOrders, OrderMappingAssist::mappingOrderlist));
        }
        vo.setRefusalReason(order.getRefusalReason());

        return vo;
    }

    public static OrderlistVO mappingEmployeeOrderlist(OrderInfoDO orderInfoDO) {
        OrderEntity order = orderInfoDO.getOrder();
        OrderlistVO vo = mappingCommonOrderlist(orderInfoDO);
        vo.setOrderStatus(order.getEmployeeOrderStatus().getCode());
        vo.setOrderStatusDesc(order.getEmployeeOrderStatus().getDesc());
        vo.setSplitFlag(BoolEnum.NO.getCode());
        vo.setRefusalReason(order.getRefusalReason());
        vo.setWayBillNumber(order.getWayBillNumber());
        vo.setFailReason(order.getFailReason());

        return vo;
    }


    public static OrderDetailVO mappingOrderDetail(OrderInfoDO orderInfo) {
        OrderDetailVO vo = new OrderDetailVO();
        OrderEntity order = orderInfo.getOrder();
        vo.setSysShopId(order.getSysShopId());
        vo.setSysOrderId(orderInfo.getSysOrderId());
        vo.setOrderNumber(order.getOrderNumber());
        vo.setEmail(order.getEmail());
        vo.setCurrentTotalPrice(order.getCurrentTotalPrice());
        vo.setFulfillmentStatus(order.getFulfillmentStatus());
        vo.setBuyerNote(order.getBuyerNote());
        vo.setSellerNote(order.getSellerNote());
        vo.setFulfillments(mappingOrderFulfillments(order.getFulfillments()));
        vo.setCustomerBusinessStatus(order.getCustomerBusinessStatus().getCode());
        vo.setEmployeeBusinessStatus(order.getEmployeeBusinessStatus().getCode());
        vo.setSplitFlag(order.getSplitFlag().getCode());
        vo.setLocalization(order.getLocalization().getCode());
        vo.setOrderProductMatchList(mappingOrderProductMatchList(orderInfo.getOrderShopProducts()));
        vo.setOrderLocalProductList(mappingOrderLocalProductList(orderInfo.getOrderLocalProducts()));
        vo.setOrderAddress(mappingOrderAddress(order.getOrderAddress()));

        vo.setChannelCode(order.getChannelCode());
        vo.setChannelEName(order.getChannelEName());
        vo.setStash(order.getStash());
        vo.setEstimatedFreight(QtBigDecimalUtil.toString(order.getEstimatedFreight(), StringUtils.EMPTY));
        vo.setRegistrationFreight(QtBigDecimalUtil.toString(order.getRegistrationFreight(), StringUtils.EMPTY));
        vo.setCurrency(order.getCurrency());

        return vo;

    }

    public static List<OrderFulfillmentVO> mappingOrderFulfillments(List<OrderFulfillmentEntity> fulfillments) {
        return QtBeanUtil.copyList(fulfillments, OrderFulfillmentVO::new);
    }


    public static List<OrderlistLineItemVO> mappingOrderLineItems(OrderInfoDO orderInfo) {
        List<OrderLocalProductDO> orderLocalProducts = orderInfo.getOrderLocalProducts();
        if (CollUtil.isNotEmpty(orderLocalProducts)) {
            return QtStreamUtil.map(mappingOrderLocalProductList(orderLocalProducts),
                    OrderMappingAssist::mappingOrderlistItem);
        }

        return QtStreamUtil.map(mappingOrderProductMatchList(orderInfo.getOrderShopProducts()),
                OrderMappingAssist::mappingOrderlistItem);
    }

    public static List<OrderLocalProductVO> mappingOrderLocalProductList(List<OrderLocalProductDO> orderLocalProducts) {
        return QtBeanUtil.copyList(orderLocalProducts, OrderLocalProductVO::new);
    }

    public static List<OrderProductMatchVO> mappingOrderProductMatchList(List<OrderShopProductDO> orderProductMatchList) {
        return QtBeanUtil.copyList(orderProductMatchList, OrderProductMatchVO::new);
    }

    public static OrderAddressVO mappingOrderAddress(OrderAddressEntity orderAddress) {
        OrderAddressVO orderAddressVO = new OrderAddressVO();
        QtBeanUtil.copyProperties(orderAddress, orderAddressVO);
        return orderAddressVO;
    }

    public static OrderlistLineItemVO mappingOrderlistItem(OrderLocalProductVO localProduct) {
        OrderlistLineItemVO vo = new OrderlistLineItemVO();
        vo.setSku(QtOptionalUtil.of(localProduct.getSku()).orElse(localProduct.getSkuId()));
        vo.setCurrentQuantity(localProduct.getCurrentQuantity());
        vo.setImgUrl(localProduct.getImgUrl());
        return vo;
    }

    public static OrderlistLineItemVO mappingOrderlistItem(OrderProductMatchVO productMatch) {
        OrderlistLineItemVO vo = new OrderlistLineItemVO();
        String localSku = StringUtils.defaultIfBlank(productMatch.getLocalSku(), productMatch.getLocalSkuId());
        String productSku = StringUtils.defaultIfBlank(productMatch.getSku(), String.valueOf(productMatch.getSkuId()));
        vo.setSku(StringUtils.defaultIfBlank(localSku, productSku));
        vo.setCurrentQuantity(productMatch.getCurrentQuantity());
        vo.setImgUrl(StringUtils.defaultIfBlank(productMatch.getLocalImgUrl(), productMatch.getImgUrl()));
        return vo;
    }

    public static OrderTabCountVO mappingTabCount(OrderEntity order) {
        OrderTabCountVO vo = new OrderTabCountVO();
        Integer bizStatus = QtOptionalUtil.of(order.getCustomerBusinessStatus())
                .map(CustomerBusinessStatusEnum::getCode)
                .orElse(null);

        Integer orderStatus = QtOptionalUtil.of(order.getCustomerOrderStatus())
                .map(CustomerOrderStatusEnum::getCode)
                .orElse(null);


        Integer tabId = ObjectUtil.defaultIfNull(bizStatus, orderStatus);
        vo.setTabId(tabId);
        vo.setCount(order.getCount());

        return vo;
    }

    public static OrderTabCountVO mappingEmployeeTabCount(OrderEntity order) {
        OrderTabCountVO vo = new OrderTabCountVO();
        Integer code = order.getEmployeeBusinessStatus().getCode();
        vo.setTabId(code);
        vo.setCount(order.getCount());

        return vo;
    }



    public static OrderProductEntity mappingOrderLocalProduct(OrderLocalProductDO orderLocalProduct) {
        OrderProductEntity res = new OrderProductEntity();
        res.setSysOrderId(orderLocalProduct.getSysOrderId());
        res.setSkuId(orderLocalProduct.getSkuId());
        res.setSkuTitle(orderLocalProduct.getSku());
        res.setPrice(orderLocalProduct.getPrice());
        res.setSysShopId(orderLocalProduct.getSysShopId());
        res.setShopProductId(orderLocalProduct.getShopProductId());
        res.setShopSkuId(orderLocalProduct.getShopSkuId());
        res.setCurrencyCode(orderLocalProduct.getCurrencyCode());
        res.setCurrentQuantity(orderLocalProduct.getCurrentQuantity());
        res.setProductType(OrderProductTypeEnum.LOCAL);
        res.setCreatedTime(LocalDateTime.now());
        res.setUpdateTime(LocalDateTime.now());
        return res;

    }

    public static OrderProductEntity mappingOrderShopProduct(OrderShopProductDO orderShopProduct) {
        OrderProductEntity res = new OrderProductEntity();
        res.setSysOrderId(orderShopProduct.getSysOrderId());
        res.setSysShopId(orderShopProduct.getSysShopId());
        res.setShopProductId(orderShopProduct.getProductId());
        res.setShopSkuId(orderShopProduct.getSkuId());
        res.setSkuId(orderShopProduct.getLocalSkuId());
        res.setSkuTitle(orderShopProduct.getLocalSku());
        res.setPrice(orderShopProduct.getPrice());
        res.setCurrentQuantity(orderShopProduct.getCurrentQuantity());
        res.setProductType(OrderProductTypeEnum.THIRD_PARTY);
        res.setCurrencyCode(orderShopProduct.getCurrencyCode());
        res.setCreatedTime(LocalDateTime.now());
        res.setUpdateTime(LocalDateTime.now());
        return res;

    }


    public static OrderEntity createSplitSubOrder(OrderEntity parentOrder,
                                                  String orderId,
                                                  String orderNumber,
                                                  OrderPackageParam orderPackage,
                                                  Map<String, OrderProductEntity> parentSkuMap) {

        OrderEntity subOrder = new OrderEntity();
        QtBeanUtil.copyProperties(parentOrder, subOrder);
        subOrder.setId(null);
        subOrder.setSysOrderId(orderId);
        subOrder.setOrderNumber(orderNumber);
        subOrder.setCurrentTotalPrice("0.00");
        subOrder.setSplitFlag(BoolEnum.YES);
        subOrder.setSourceOrderNumber(parentOrder.getSysOrderId());
        subOrder.setLocalization(BoolEnum.YES);
        subOrder.setDataStatus(DataStatusEnum.ENABLE);
        subOrder.setCreatedTime(LocalDateTime.now());
        subOrder.setUpdateTime(LocalDateTime.now());
        subOrder.setChannelCode("");
        subOrder.setEstimatedFreight(null);
        subOrder.setRegistrationFreight(null);


        List<OrderProductEntity> orderProducts = QtStreamUtil.filterAndMap(orderPackage.getPackageSkuList(),
                sku -> sku.getCount() > 0,
                sku -> {
                    OrderProductEntity orderProduct = new OrderProductEntity();
                    QtBeanUtil.copyProperties(parentSkuMap.get(sku.getLocalSkuId()), orderProduct);

                    orderProduct.setSysOrderId(orderId);
                    orderProduct.setCurrentQuantity(sku.getCount());
                    orderProduct.setProductType(OrderProductTypeEnum.LOCAL);
                    orderProduct.setCreatedTime(LocalDateTime.now());
                    orderProduct.setUpdateTime(LocalDateTime.now());
                    return orderProduct;
                });

        subOrder.setOrderLineItems(orderProducts);

        OrderAddressEntity orderAddress = parentOrder.getOrderAddress();
        OrderAddressEntity subOrderAddress = new OrderAddressEntity();
        BeanUtil.copyProperties(orderAddress, subOrderAddress);
        subOrderAddress.setSysOrderId(orderId);

        subOrder.setOrderAddress(subOrderAddress);

        return subOrder;

    }

    public static OrderlistVO mappingCommonOrderlist(OrderInfoDO orderInfoDO) {
        OrderlistVO vo = new OrderlistVO();
        OrderEntity order = orderInfoDO.getOrder();
        vo.setSysShopId(order.getShopInfo().getSysShopId());
        vo.setShopName(order.getShopInfo().getShopName());
        vo.setPlatForm(order.getShopInfo().getPlatForm().getCode());
        vo.setSysOrderId(orderInfoDO.getSysOrderId());
        vo.setOrderNumber(order.getOrderNumber());
        vo.setEmail(order.getEmail());
        vo.setCurrentTotalPrice(order.getCurrentTotalPrice());
        vo.setLineItems(mappingOrderLineItems(orderInfoDO));
        vo.setOrderAddress(mappingOrderAddress(order.getOrderAddress()));
        vo.setCreatedAt(order.getCreatedAt());
        vo.setBuyerNote(order.getBuyerNote());
        vo.setSellerNote(order.getSellerNote());
        vo.setFulfillments(mappingOrderFulfillments(order.getFulfillments()));
        vo.setShippingMethod(order.getShippingMethod());
        vo.setFulfillmentTime(order.getFulfillmentTime());
        vo.setDeliveryTime(order.getDeliveryTime());
        vo.setOrderStockStatus(order.getOrderStockStatus().getCode());

        vo.setChannelCode(order.getChannelCode());
        vo.setChannelEName(order.getChannelEName());
        vo.setStash(order.getStash());
        vo.setEstimatedFreight(QtBigDecimalUtil.toString(order.getEstimatedFreight(), StringUtils.EMPTY));
        vo.setRegistrationFreight(QtBigDecimalUtil.toString(order.getRegistrationFreight(), StringUtils.EMPTY));
        vo.setCurrency(order.getCurrency());
        return vo;
    }

    public static List<OrderProductEntity> mappingOrderProductEntityList(OrderInfoDO orderInfoDO) {
        List<OrderLocalProductDO> orderLocalProducts = orderInfoDO.getOrderLocalProducts();
        if (CollUtil.isNotEmpty(orderLocalProducts)) {
            return QtStreamUtil.map(orderLocalProducts, OrderMappingAssist::mappingOrderLocalProduct);
        }

        return QtStreamUtil.map(orderInfoDO.getOrderShopProducts(), OrderMappingAssist::mappingOrderShopProduct);

    }

}
